package de.g18.scavengerhunt.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;

import de.g18.scavengerhunt.AppApplicationContext;
import de.g18.scavengerhunt.AppConstants;
import de.g18.scavengerhunt.R;
import de.g18.scavengerhunt.types.BattleZone;
import de.g18.scavengerhunt.types.Session;
import de.g18.scavengerhunt.utils.GameUtils;
import de.g18.scavengerhunt.utils.WebserviceUtil;

/**
 * This is the activity for the list of all active games
 */
public class GamesActivity extends Activity {

    private WebserviceUtil      webserviceUtil  = null;

    private Session             selectedSession = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.games);

        webserviceUtil = WebserviceUtil.getInstance();
        webserviceUtil.setContext(this);
        webserviceUtil.handleUserRegistration();

        TextView lblUsername = (TextView) findViewById(R.id.txtUsername);
        lblUsername.setText(getString(R.string.username) + " " + AppApplicationContext.getUser().getName());

        List<Map<String, String>> sessions = new ArrayList<Map<String, String>>();
        for (Session game : getAvailableSessions()) {
            String gameJoined = (AppApplicationContext.getSession() != null && AppApplicationContext.getSession().getId() == game.getId()) ? getString(R.string.joined) : "";

            Map<String, String> map = new HashMap<String, String>();
            map.put("id", String.valueOf(game.getId()));
            map.put("name", game.getName());
            map.put("numPlayers", String.valueOf(game.getNumPlayers()));
            map.put("maxPlayers", String.valueOf(game.getMaxPlayers()));
            map.put("isRunning", String.valueOf(game.isRunning()));
            map.put("mrXUserId", String.valueOf(game.getEvaderUserId()));
            map.put("isJoined", gameJoined);
            map.put("start", game.getStartTime());
            map.put("bzName", game.getBattleZone().getName());
            map.put("bzLat", String.valueOf(game.getBattleZone().getCircleCenter().getLatitudeE6()));
            map.put("bzLng", String.valueOf(game.getBattleZone().getCircleCenter().getLongitudeE6()));
            map.put("bzRadius", String.valueOf(game.getBattleZone().getRadiusInMeters()));
            sessions.add(map);
        }

        SimpleAdapter sa = new SimpleAdapter(this, sessions, R.layout.games_item, new String[] {"name", "isJoined", "start"}, new int[] {R.id.gameName, R.id.lblGameJoined, R.id.lblSessionStartTime});
        final ListView lstGames = (ListView) findViewById(R.id.lstGames);
        lstGames.setAdapter(sa);
        lstGames.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                @SuppressWarnings("unchecked") // we now, what we've put in this map...
                HashMap<String, String> obj = (HashMap<String, String>) parent.getItemAtPosition(position);
                selectedSession = new Session(Integer.valueOf(obj.get("id")), (String) obj.get("name"), Integer.valueOf(obj.get("mrXUserId")), new BattleZone(new GeoPoint(Integer.valueOf(obj
                        .get("bzLat")), Integer.valueOf(obj.get("bzLng"))), Integer.valueOf(obj.get("bzRadius"))), obj.get("start"));
                selectedSession.getBattleZone().setName((String) obj.get("bzName"));

                if (AppApplicationContext.getSession() != null && AppApplicationContext.getSession().getId() != selectedSession.getId()) {
                    showDialog(AppConstants.DIALOG_JOIN_GAME_WHILE_INGAME_MESSAGE);
                } else {
                    joinGameSession(selectedSession);
                }
            }
        });
    }

    private List<Session> getAvailableSessions() {
        List<Session> sessions = new ArrayList<Session>();
        sessions = webserviceUtil.getActiveSessions();

        if (sessions.size() == 0) {
            Toast.makeText(getApplicationContext(), getString(R.string.noGamesFound), Toast.LENGTH_SHORT).show();
        }
        return sessions;
    }

    private boolean joinSession(Session session) {
        return webserviceUtil.addUserToSession(AppApplicationContext.getUser(), session);
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        Dialog dialog = null;
        switch (id) {
            case AppConstants.DIALOG_JOIN_GAME_WHILE_INGAME_MESSAGE:
                dialog = new AlertDialog.Builder(this).setMessage(getString(R.string.dialogJoinGameWhileIngameMessage)).setTitle(getString(R.string.dialogJoinGameWhileIngameTitle))
                        .setPositiveButton(getString(R.string.yes).toUpperCase(), new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                joinGameSession(selectedSession);
                            }
                        }).setNegativeButton(getString(R.string.abort), new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.cancel();
                            }
                        }).create();
        }
        return dialog;
    }

    /**
     * Called automatically when the Activity has been created and will be visible to the user.
     */
    @Override
    protected void onStart() {
        super.onStart();

        // Give the ApplicationContext the current activity instance.
        AppApplicationContext.setActivity(this);
    }

    private void joinGameSession(Session session) {
        // TODO Remove user from current session in webservice.
        AppApplicationContext.setSession(null);

        // Try to join the session.
        if (joinSession(session)) {
            // Save the current active session in our ApplicationContext.
            AppApplicationContext.setSession(session);
            GameUtils.showActivity(new GameMapActivity());
        } else {
            Toast.makeText(getApplicationContext(), getString(R.string.joiningToGame) + " '" + session.getName() + "' " + getString(R.string.failed), Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * This override makes sure, that the device back button only intents to load the MainMenuActivity.
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            GameUtils.showActivity(new MainMenuActivity());
            return false;
        }

        return super.onKeyDown(keyCode, event);
    }
}
